package com.qunar.crawler.utils;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.BitSet;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;

import library.functions.Function2PV;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.RandomUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author waynechen Mar 12, 2012 11:23:14 AM
 */
public class ConfigUtils {
    private static final Logger logger = LoggerFactory.getLogger(ConfigUtils.class);
    
    private static String hour;
	private static String min;
	private static String sec;
	
	private static String intervalDay;
	

	public static String getIntervalDay() {
		return intervalDay;
	}

	public static void setIntervalDay(String intervalDay) {
		ConfigUtils.intervalDay = intervalDay;
	}

	public static String getHour() {
		return hour;
	}

	public static void setHour(String hour) {
		ConfigUtils.hour = hour;
	}

	public static String getMin() {
		return min;
	}

	public static void setMin(String min) {
		ConfigUtils.min = min;
	}

	public static String getSec() {
		return sec;
	}

	public static void setSec(String sec) {
		ConfigUtils.sec = sec;
	}

	static{
		Properties props = new Properties();
		try {
			//props.load(JdbcUtils.class.getClassLoader().getResourceAsStream("jdbc.properties"));
			//props.load(new FileInputStream(JdbcUtils.class.getClassLoader().getResource("jdbc.properties").getPath()));
			props.load(new FileInputStream("config.properties"));
		} catch (IOException e) {
			e.printStackTrace();
		}

		hour = props.getProperty("hour");
		min = props.getProperty("min");
		sec = props.getProperty("sec");
		intervalDay = props.getProperty("intervalDay");
		System.out.println("爬虫启动时间："+hour+":"+min+":"+sec+",抓取时间间隔: "+intervalDay+" 天");
	}

    /** 从配置文件中拿代理IP和端口 */
    public static LinkedList<ProxySetting> getProxyList() {
        LinkedList<ProxySetting> list = new LinkedList<ProxySetting>();
        // String path = ConfigBatchInit.class.getClassLoader().getResource("proxyList").getFile();
        InputStream is = ConfigUtils.class.getClassLoader().getResourceAsStream("newProxyList");
        getListAsStream(is, list, new Function2PV<List<?>, String>() {
            @SuppressWarnings("unchecked")
            @Override
            public void apply(List<?> a, String line) {
                List<ProxySetting> aa = (List<ProxySetting>) a;
                String[] split = line.split(":");
                aa.add(new ProxySetting(split[0], Integer.parseInt(split[1])));
            }
        });
        Collections.shuffle(list);
        return list;
    }

//    /** 从配置文件中拿117GO的马甲账号 */
//    public static LinkedList<Account> getAccountList() {
//        LinkedList<Account> list = new LinkedList<Account>();
//        // String path = ConfigBatchInit.class.getClassLoader().getResource("accountList").getPath();
//        InputStream is = ConfigUtils.class.getClassLoader().getResourceAsStream("accountList");
//        getListAsStream(is, list, new Function2PV<List<?>, String>() {
//            @SuppressWarnings("unchecked")
//            @Override
//            public void apply(List<?> a, String line) {
//                List<Account> aa = (List<Account>) a;
//                String[] split = line.split(":");
//                aa.add(new Account(split[0], split[1]));
//            }
//        });
//        Collections.shuffle(list);
//        return list;
//    }
//
//    /** 从配置文件中拿代理浏览器类型 */
//    public static LinkedList<Account> getAgenttList() {
//        LinkedList<Account> list = new LinkedList<Account>();
//        // String path = ConfigBatchInit.class.getClassLoader().getResource("userAgentList").getPath();
//        InputStream is = ConfigUtils.class.getClassLoader().getResourceAsStream("userAgentList");
//        getListAsStream(is, list, new Function2PV<List<?>, String>() {
//            @SuppressWarnings("unchecked")
//            @Override
//            public void apply(List<?> a, String line) {
//                List<Account> aa = (List<Account>) a;
//                String[] split = line.split(":");
//                aa.add(new Account(split[0], split[1]));
//            }
//        });
//        Collections.shuffle(list);
//        return list;
//    }

    public static List<String> getStringList(String confFileName) {
        List<String> list = new LinkedList<String>();
        // String path = ConfigBatchInit.class.getClassLoader().getResource(confFileName).getPath();
        InputStream is = ConfigUtils.class.getClassLoader().getResourceAsStream(confFileName);
        getListAsStream(is, list, new Function2PV<List<?>, String>() {
            @SuppressWarnings("unchecked")
            @Override
            public void apply(List<?> a, String line) {
                List<String> aa = (List<String>) a;
                aa.add(line);
            }
        });
        return list;
    }

    private static void getList(String path, List<?> list, Function2PV<List<?>, String> func) {

       // System.out.println("path:" + path);
        File f = new File(path);
        if (!f.exists())
            return;

        FileReader in = null;
        BufferedReader reader = null;
        try {
            in = new FileReader(f);
            reader = new BufferedReader(in);
            String line;
            while (null != (line = reader.readLine())) {
                line = line.trim();
                if (StringUtils.isEmpty(line))
                    continue;
                // 注释掉的就跳过
                else if (line.startsWith("#"))
                    continue;
                else {
                    if (line.indexOf("#") != -1)
                        line = line.substring(0, line.indexOf("#"));
                    line = line.trim();
                    func.apply(list, line);
                }
            }
        } catch (FileNotFoundException e) {
            logger.error(e.getLocalizedMessage());
        } catch (IOException e) {
            logger.error(e.getLocalizedMessage());
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private static void getListAsStream(InputStream is, List<?> list, Function2PV<List<?>, String> func) {

        if (is == null)
            return;

        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new InputStreamReader(is));
            String line;
            while (null != (line = reader.readLine())) {
                line = line.trim();
                if (StringUtils.isEmpty(line))
                    continue;
                // 注释掉的就跳过
                else if (line.startsWith("#"))
                    continue;
                else {
                    if (line.indexOf("#") != -1)
                        line = line.substring(0, line.indexOf("#"));
                    line = line.trim();
                    func.apply(list, line);
                }
            }
        } catch (FileNotFoundException e) {
            logger.error(e.getLocalizedMessage());
        } catch (IOException e) {
            logger.error(e.getLocalizedMessage());
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    // ---------------------bit set---------------------------

    public static BitSet loadBitSet(File file) {
        if (file == null || !file.exists())
            return null;
        ObjectInputStream in = null;
        BitSet bitSet = null;
        try {
            in = new ObjectInputStream(new FileInputStream(file));
            bitSet = (BitSet) in.readObject();
        } catch (Exception e) {
            logger.error(e.getLocalizedMessage());
        } finally {
            if (in != null)
                try {
                    in.close();
                } catch (IOException e) {
                    logger.error(e.getLocalizedMessage());
                }
        }
        return bitSet;
    }

    public static void saveBitSet(BitSet bits, File file) {
        if (bits == null || file == null)
            return;
        if (file.exists())
            file.delete();
        ObjectOutputStream out = null;
        try {
            out = new ObjectOutputStream(new FileOutputStream(file));
            out.writeObject(bits);
        } catch (IOException e) {
            logger.error(e.getLocalizedMessage());
        } finally {
            if (out != null)
                try {
                    out.close();
                } catch (IOException e) {
                    logger.error(e.getLocalizedMessage());
                }
        }
    }

    /** 获得随机代理 */
    public static synchronized ProxySetting getRandomProxySetting() {

        List<ProxySetting> proxys = getProxyList();

        //System.out.println("proxys size -----------" + proxys.size());
        int radomIndex = RandomUtils.nextInt(proxys.size());

        return proxys.get(radomIndex);

    }

    /** 获得随机代理浏览器 */
    public static synchronized String getRandomAgent() {

        List<String> agents = getStringList("userAgentList");

        int radomIndex = RandomUtils.nextInt(agents.size());

        return agents.get(radomIndex);

    }

}
